package com.fyy.socketweb.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author fyy
 * @Description WebSocket核心类
 * @Date 2021/1/4 16:37
 */
@Slf4j
@Component
@ServerEndpoint("/websocket/{sid}")
public class WebSocketServer {

    //记录当前在线数,线程安全
    private static AtomicInteger onlineNum = new AtomicInteger();
    //记录每个客户端的WebSocketServer对象
    private static ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();

    /**
     * @Author fyy
     * @Description 发送消息
     * @param session 客户端
     * @param msg 消息体
     * @Date 2021/1/4 16:42
     */
    public void sendMsg(Session session,String msg) throws IOException {
        if(null != session){
            synchronized (session){
                log.info("发送消息:客户端:{}，消息:{}",session.getId(),msg);
                session.getBasicRemote().sendText(msg); //发送消息
            }
        }
    }

    /**
     * @Author fyy
     * @Description 发送消息
     * @param userName 用户名
     * @param msg 消息体
     * @Date 2021/1/4 16:42
     */
    public void sendMsgToUser(String userName,String msg) throws IOException {
        Session session = sessions.get(userName);
        sendMsg(session,msg); //发送消息
    }

    /**
     * @Author fyy
     * @Description 建立连接成功调用,记录用户信息
     * @param session 客户端
     * @param userName 用户名
     * @Date 2021/1/4 16:42
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("sid") String userName) throws IOException {
        sessions.put(userName,session); //保存用户信息
        addOnlineCount(); //在线数自增 +1
        log.info("欢迎{}登录！",userName);
        sendMsgToUser(userName,"欢迎" + userName + "登录!");
    }

    /**
     * @Author fyy
     * @Description 关闭连接时调用
     * @param userName 用户名
     * @Date 2021/1/4 16:42
     */
    @OnClose
    public void onClose(@PathParam("sid") String userName){
        sessions.remove(userName); //删除对应用户连接
        subOnlineCount(); //在线计数递减 -1
        log.info("{}断开连接,当前在线客户数{}!",userName,onlineNum);
    }

    /**
     * @Author fyy
     * @Description 收到客户端信息
     * @param msg 消息体
     * @Date 2021/1/4 16:42
     */
    @OnMessage
    public void onMsg(String msg){
        msg = "客户端:" + msg + ",已收到";
        log.info(msg);
        for (Session session : sessions.values()) {
            try {
                sendMsg(session,msg);
            } catch (IOException e) {
                log.error("客户端：{}接收消息异常！",session.getId());
                continue; //异常继续，确保其他客户端可以收到消息
            }
        }
    }

    //在线数自增
    public static void addOnlineCount(){
        onlineNum.incrementAndGet();
    }

    //在线数自减
    public static void subOnlineCount(){
        onlineNum.decrementAndGet();
    }



}
